package com.chj.chuji.tijie14;

import java.util.ArrayList;

// https://blog.csdn.net/Q755100802/article/details/89789303
//https://blog.csdn.net/xianpingping/article/details/83447668
public class BlueMage03 {

	public static void dfs(int u) {
		siz[u] = 1;
		dp[u][1] = 1;

		int bb = 0;
		if (G[u] != null) {
			bb = G[u].arr.size();
		} else {
			bb = 0;
		}

		for (int i = 0; i < bb; i++) {
//			int v=G[u][i];
			int v = G[u].arr.get(i);
			dfs(v);
//			ll temp[maxn];
//			memset(temp,0,sizeof(temp));
			int[] temp = new int[maxn];
			for (int ii = 1; ii <= siz[u]; ii++) {
				for (int j = 0; j <= Math.min(k - ii, siz[v]); j++) {
					// 当前连通块大小为ii+j，其中ii来自之前访问过的子节点，j来自现在正在访问的子节点，计数原理为乘
					temp[ii + j] = (temp[ii + j] % mod + dp[u][ii] * dp[v][j] % mod) % mod;
				}
			}
			for (int j = 1; j <= k; j++) {
				dp[u][j] = temp[j];
			}
			siz[u] += siz[v];
		}
		for (int i = 1; i <= k; i++) {
			dp[u][0] += dp[u][i];
			dp[u][0] %= mod;
		}
	}

	public static class ArrList {
		public ArrayList<Integer> arr;

		public ArrList() {
			arr = new ArrayList<Integer>();
		}
	}

	public static final int mod = 998244353;
	public static final int maxn = 2000 + 10;
	public static ArrList[] G = new ArrList[maxn];
	public static int[][] dp = new int[maxn][maxn];
	public static int n;
	public static int k;
	public static int[] siz = new int[maxn];
//	vector<int>G[maxn];
//	ll dp[maxn][maxn];
//	ll n, k;ll siz[maxn];// 每个节点的子节点个数

	public static void main(String[] args) {
//		for(int i=1;i<n;i++){
//            int u,v;
//            scanf("%d%d",&u,&v);
//            G[u].push_back(v);
//    	}
//    	memset(dp,0,sizeof(dp));
//    	dfs(1);
//    	printf("%lld\n",dp[1][0]);

		n = 5;
		k = 2;

		ArrList arr02 = new ArrList();
		arr02.arr.add(2);
		arr02.arr.add(3);
		G[1] = arr02;

//		ArrList arr03 = new ArrList();
//		arr03.arr.add(3);
//		G[1] = arr03;

		ArrList arr04 = new ArrList();
		arr04.arr.add(4);
		arr04.arr.add(5);
		G[2] = arr04;

//		ArrList arr05 = new ArrList();
//		arr05.arr.add(5);
//		G[2] = arr05;
		dfs(1);
		System.out.println(dp[1][0]);
	}
}

//	#include<bits/stdc++.h>
//
//	using namespace std;typedef long
//	long LL;const
//	int maxn = 10000;const
//	int mod = 998244353;LL dp[maxn][maxn];vector<int>G[maxn];int temp[maxn];int siz[maxn];
//int n,k;
//
//void dfs(int u,int fa){
//    dp[u][1]=1;
//    siz[u]=1;
//    int v;
//    for(int i=0;i<G[u].size();i++){
//        v=G[u][i];
//        if(v==fa)
//            continue;
//        dfs(v,u);
//        memset(temp,0,sizeof(temp));
//        for(int ii=1;ii<=siz[u];ii++){
//            for(int j=0;j<=min(k-ii,siz[v]);j++){
//                temp[ii+j]=(temp[ii+j]%mod+dp[u][ii]*dp[v][j]%mod)%mod;
//            }
//        }
//        for(int ii=1;ii<=k;ii++){
//            dp[u][ii]=temp[ii];
//        }
//        siz[u]+=siz[v];
//    }
//    for(int i=1;i<=k;i++)///到最末端节点
//    {
//    ///    cout<<"*******dp["<<u<<"]["<<0<<"]:"<<dp[u][0]<<endl;
//        dp[u][0] = (dp[u][0]+dp[u][i])%mod;
//    }
//}
//
//int main()
//{
//    int a,b;
//    while(scanf("%d%d",&n,&k)!=EOF){
//        for(int i=1;i<=n-1;i++){
//            scanf("%d%d",&a,&b);
//            G[a].push_back(b);
//            G[b].push_back(a);
//        }
//        dfs(1,0);
//        cout<<dp[1][0]<<endl;
//    }
//    return 0;
//}

//#include <cstdio>
//#include <cstring>
//#include <algorithm>
//#include <iostream>
//#include <vector>
//#include <cmath>
//using namespace std;
//typedef long long ll;
//const ll mod=998244353;
//const int maxn=2000+10;
//vector<int>G[maxn];
//ll dp[maxn][maxn];
//ll n,k;
//ll siz[maxn];//每个节点的子节点个数
//void dfs(int u){
//	siz[u]=1;
//	dp[u][1]=1;
//	for(int i=0;i<G[u].size();i++){
//		int v=G[u][i];
//		dfs(v);
//		ll temp[maxn];
//		memset(temp,0,sizeof(temp));
//		for(int ii=1;ii<=siz[u];ii++){
//            for(int j=0;j<=min(k-ii,siz[v]);j++){
//            	//当前连通块大小为ii+j，其中ii来自之前访问过的子节点，j来自现在正在访问的子节点，计数原理为乘
//            	temp[ii+j]=(temp[ii+j]%mod+dp[u][ii]*dp[v][j]%mod)%mod;
//            }
//		}
//		for(int j=1;j<=k;j++){
//			dp[u][j]=temp[j];
//		}
//		siz[u]+=siz[v];
//	}
//	for(int i=1;i<=k;i++){
//		dp[u][0]+=dp[u][i];
//		dp[u][0]%=mod;
//	}
//}
// 
//int main(){
//    while(scanf("%lld%lld",&n,&k)!=EOF){
//    	for(int i=1;i<n;i++){
//            int u,v;
//            scanf("%d%d",&u,&v);
//            G[u].push_back(v);
//    	}
//    	memset(dp,0,sizeof(dp));
//    	dfs(1);
//    	printf("%lld\n",dp[1][0]);
//    }
//    return 0;
//}
